package cn.lili.modules.promotion.serviceimpl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.client.VipClient;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.promotion.entity.dos.ReturnActivity;
import cn.lili.modules.promotion.entity.dos.ReturnActivityUser;
import cn.lili.modules.promotion.entity.enums.ReturnActivityTimeEnum;
import cn.lili.modules.promotion.entity.enums.ReturnActivityUserSourceEnum;
import cn.lili.modules.promotion.entity.enums.ReturnActivityUserStatusEnum;
import cn.lili.modules.promotion.entity.enums.ReturnActivityUserUseEnum;
import cn.lili.modules.promotion.manage.ReturnActivityManage;
import cn.lili.modules.promotion.mapper.ReturnActivityUserMapper;
import cn.lili.modules.promotion.service.ReturnActivityGoodsService;
import cn.lili.modules.promotion.service.ReturnActivityUserService;
import cn.lili.modules.system.client.DictionaryClient;
import cn.lili.modules.system.entity.dos.Dictionary;
import cn.lili.modules.system.entity.dos.LiVip;
import cn.lili.util.TemplateHtml;
import cn.lili.util.TemplateMessage;
import cn.wildfirechat.pojos.SendMessageResult;
import cn.wildfirechat.sdk.ChannelServiceApi;
import cn.wildfirechat.sdk.model.IMResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.api.UserApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pojos.OpenAppUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class ReturnActivityUserServiceImpl extends ServiceImpl<ReturnActivityUserMapper, ReturnActivityUser> implements ReturnActivityUserService {

    @Resource
    private ReturnActivityManage returnActivityManage;

    private final VipClient vipClient;

    private final ReturnActivityGoodsService returnActivityGoodsService;

    private final DictionaryClient dictionaryClient;

    private final UserClient userClient;

    private final RedissonClient redisson;

    private final ChannelServiceApi channelServiceApi;

    private final UserApi userApi;

    @Override
    public Boolean generate(String userId,OrderItem orderItem) {
        Dictionary dict = dictionaryClient.getDict(Dictionary.builder().code("green_score_return").build());
        log.info("=====dict开关====={}", JSON.toJSONString(dict));
        if (dict == null || "0".equals(dict.getValue())) {
            // 非会员用户 不参与返券
            LiVip vip = vipClient.getByUserId(userId);
            if (null == vip || vip.getVipStatus() != 1) {
                return false;
            }

            // 非全返商品不参与返券
            if (!returnActivityGoodsService.isReturnActivityGoods(orderItem.getGoodsId())) {
                return false;
            }
        }


        //1.解析金额，获取全返卷面额
        List<ReturnActivity> list = returnActivityManage.initReturnActivity(orderItem.getFlowPrice().intValue());

        //2.构建奖奖券
        list.forEach(e->{
            ReturnActivityUser returnActivityUser = ReturnActivityUser.builder()
                    .name(e.getName())
                    .price(e.getPrice())
                    .status(dict == null || "0".equals(dict.getValue()) ? ReturnActivityUserStatusEnum.TAKE_EFFECT.getCode() : ReturnActivityUserStatusEnum.UN_TAKE_EFFECT.getCode())
                    .useStatus(ReturnActivityUserUseEnum.UN_USE.getCode())
                    .userId(userId)
                    .orderSn(orderItem.getOrderSn())
                    .orderItemSn(orderItem.getSn())
                    .effectiveTimeCode(e.getEffectiveTimeCode())
                    .source(ReturnActivityUserSourceEnum.BUY_GOODS.getCode())
                    .build();
            this.save(returnActivityUser);
        });
        return true;
    }

    @Override
    public Boolean updateStatus(String userId,String orderSn, String orderItemSn) {
        //查询
        LambdaQueryWrapper<ReturnActivityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReturnActivityUser::getUserId,userId);
        queryWrapper.eq(ReturnActivityUser::getOrderSn,orderSn);
        queryWrapper.eq(StringUtils.isNotEmpty(orderItemSn),ReturnActivityUser::getOrderItemSn,orderItemSn);
        queryWrapper.eq(ReturnActivityUser::getDeleteFlag,false);
        List<ReturnActivityUser> returnActivityUserList = this.list(queryWrapper);
        if(returnActivityUserList==null || returnActivityUserList.isEmpty()){
            return false;
        }


        //修改生效状态为已生效，有效开始时间，有效结束时间
        returnActivityUserList.forEach(e->{
            LambdaUpdateWrapper<ReturnActivityUser> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.set(ReturnActivityUser::getStatus,ReturnActivityUserStatusEnum.UN_TAKE_EFFECT.getCode());
            lambdaUpdateWrapper.set(ReturnActivityUser::getBeginTime, LocalDate.now());
            if(e.getEffectiveTimeCode()!=null){
                lambdaUpdateWrapper.set(ReturnActivityUser::getEndTime,returnActivityManage.renderTime(LocalDate.now(), ReturnActivityTimeEnum.valueOf(e.getEffectiveTimeCode())));
            }
            lambdaUpdateWrapper.eq(ReturnActivityUser::getId, e.getId());
            this.update(lambdaUpdateWrapper);
        });
        return true;
    }

    @Override
    public Boolean updateUseStatus(String id, String useStatus) {
        LambdaUpdateWrapper<ReturnActivityUser> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(ReturnActivityUser::getId,id);
        lambdaUpdateWrapper.set(ReturnActivityUser::getUseStatus,useStatus);
        return this.update(lambdaUpdateWrapper);
    }

    @Override
    public List<ReturnActivityUser> getList(String userId, String useStatus) {
        LambdaQueryWrapper<ReturnActivityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReturnActivityUser::getUserId,userId);
        queryWrapper.eq(ReturnActivityUser::getDeleteFlag,false);
        if (CharSequenceUtil.isNotEmpty(useStatus)) {
            if (useStatus.equals("2")) { // 已过期的 查询已过期和已失效
                queryWrapper.in(ReturnActivityUser::getUseStatus, Arrays.asList("2", "3"));
            }else {
                queryWrapper.eq(ReturnActivityUser::getUseStatus, useStatus);
            }
        }
        return this.list(queryWrapper);
    }

    @Override
    public Boolean updateBecomeDue() {
        //查询已生效，未使用的全返卷
        LambdaUpdateWrapper<ReturnActivityUser> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(ReturnActivityUser::getDeleteFlag,false);
        queryWrapper.eq(ReturnActivityUser::getStatus,ReturnActivityUserStatusEnum.UN_TAKE_EFFECT.getCode());
        queryWrapper.eq(ReturnActivityUser::getUseStatus,ReturnActivityUserUseEnum.UN_USE.getCode());
        List<ReturnActivityUser> returnActivityUserList = this.list(queryWrapper);
        if(returnActivityUserList == null || returnActivityUserList.isEmpty()){
            return false;
        }

        //更新时间到期的状态
        returnActivityUserList.forEach(e->{
            // 比较结束时间和当前时间
            if(e.getEndTime().before(new Date())){
                updateUseStatus(e.getId(),ReturnActivityUserUseEnum.EXPIRED.getCode());
            }
        });

        return true;
    }

    /**
     * 获取用户全返券数量
     * @return
     */
    @Override
    public long getUserReturnActivityNum () {
        LambdaQueryWrapper<ReturnActivityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReturnActivityUser::getUserId, UserContext.getCurrentId());
        queryWrapper.eq(ReturnActivityUser::getUseStatus, 0);
        return this.count(queryWrapper);
    }

    /**
     * 删除用户全返卷
     * @param userId
     * @param orderItemSn
     * @return
     */
    @Override
    public boolean deleteUserReturnActivity (String userId, String orderItemSn) {
        LambdaQueryWrapper<ReturnActivityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReturnActivityUser::getUserId, userId);
        queryWrapper.eq(ReturnActivityUser::getOrderItemSn, orderItemSn);
        return this.remove(queryWrapper);
    }


    /**
     * 根据订单号删除用户全返卷
     * @param userId
     * @return
     */
    @Override
    public boolean deleteUserReturnActivityByOrderSn (String userId, String orderSn) {
        LambdaUpdateWrapper<ReturnActivityUser> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(ReturnActivityUser::getUserId, userId);
        queryWrapper.eq(ReturnActivityUser::getOrderSn, orderSn);
        queryWrapper.set(ReturnActivityUser::getUseStatus, ReturnActivityUserUseEnum.CANCEL.getCode());
        return this.update(queryWrapper);
    }


    /**
     * 生成全返券
     * @param openId
     * @return
     */
    @Override
    public ResultMessage<Object> generate(String openId, String orderSn, Double price) {
        if (StringUtils.isEmpty(openId) || null == price) {
            return ResultUtil.error(500, "参数错误");
        }

        RLock lock = redisson.getLock("generate_return_activity_" + openId);
        try {
            User user = userClient.getByOpenId(openId, SceneEnums.MEMBER.name());
            if (null == user) {
                return ResultUtil.error(500, "用户不存在");
            }

            //1.解析金额，获取全返卷面额
            List<ReturnActivity> list = returnActivityManage.initReturnActivity(price.intValue());

            //2.构建奖奖券
            list.forEach(e->{
                ReturnActivityUser returnActivityUser = ReturnActivityUser.builder()
                        .name(e.getName())
                        .price(e.getPrice())
                        .status(ReturnActivityUserStatusEnum.UN_TAKE_EFFECT.getCode())
                        .useStatus(ReturnActivityUserUseEnum.UN_USE.getCode())
                        .userId(user.getId())
                        .orderSn(orderSn)
                        .orderItemSn(orderSn)
                        .effectiveTimeCode(e.getEffectiveTimeCode())
                        .source(ReturnActivityUserSourceEnum.MEETING.getCode())
                        .build();
                this.save(returnActivityUser);
            });
            if (StringUtils.isNotEmpty(user.getOpenId())) {
                OpenAppUser openAppUser = userApi.getUserinfoByOpenId(user.getOpenId());
                if (null != openAppUser) {
                    List<String> targets = new ArrayList<>();

                    targets.add(openAppUser.getUId());
                    TemplateMessage message = TemplateHtml.sendCouponMessageForHtml("飞语会议全返券到账", orderSn, "飞语会议返券");
                    try {
                        IMResult<SendMessageResult> sendMessageResultIMResult = channelServiceApi.sendMessage(0, targets, message);
                        log.info("发送全返券消息结果：{}", JSONObject.toJSONString(sendMessageResultIMResult));
                    } catch (Exception ex) {
                        log.error("发送消息失败", ex);
                        throw new RuntimeException(ex);
                    }
                }
            }
            return ResultUtil.success();
        }catch (Exception e) {
            log.error("生成全返券失败", e);
        }finally {
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
        return ResultUtil.error(500, "全返券发放失败");
    }
}
